package com.changgou.seckill.comsumer;

import com.alibaba.fastjson.JSON;
import com.changgou.entity.SystemConstants;
import com.changgou.pay.feign.WeixinPayFeign;
import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.dao.SeckillOrderMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import com.changgou.seckill.pojo.SeckillOrder;
import com.changgou.seckill.pojo.SeckillStatus;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author liyipeng
 * @date 2021-07-03 14:09
 */
@Component
//监听某一个队列的消息
@RabbitListener(queues = "queue.seckillorder")
public class SeckillUpdateOrderListener {

    @Autowired
    private SeckillOrderMapper seckillOrderMapper;

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private WeixinPayFeign weixinPayFeign;

    @Autowired
    private RedisTemplate redisTemplate;

    @RabbitHandler//指定该方法处理字符串类型的消息
    public void jieshouMessage(String msg) throws Exception {
        //1. 接收消息本身 转成MAP对象
        Map<String, String> map = JSON.parseObject(msg, Map.class);
        if (map != null) {
            //通信成功
            if (map.get("return_code").equalsIgnoreCase("SUCCESS")) {

                String attachString = map.get("attach");//{username:zhangsan,type:1}
                Map<String, String> attachMap = JSON.parseObject(attachString, Map.class);
                String username = attachMap.get("username");

                //业务成功 支付成功
                if (map.get("result_code").equalsIgnoreCase("SUCCESS")) {

                    //2. 获取到支付的成功/失败的状态  如果是成功 将redis的订单存到数据库 并删除redis的订单

                    //获取订单 存储到mysql
                    SeckillOrder seckillOrder = (SeckillOrder) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).get(username);
                    //支付成功
                    seckillOrder.setStatus("1");
                    String time_end = map.get("time_end");
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
                    Date date = simpleDateFormat.parse(time_end);
                    seckillOrder.setPayTime(date);
                    seckillOrder.setTransactionId(map.get("transaction_id"));
                    seckillOrderMapper.insertSelective(seckillOrder);
                    //删除redis中的订单
                    redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).delete(username);
                    //清除重复排队标识
                    redisTemplate.boundHashOps(SystemConstants.SEC_KILL_QUEUE_REPEAT_KEY).delete(username);
                    //清除用户的抢单信息
                    redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).delete(username);

                } else {
                    //3. 如果  1.关闭微信支付订单 2.失败回滚库存 3.删除预订单 4.清除标记
                    // 获取秒杀商品对象  +1

                    SeckillStatus seckillStatus = (SeckillStatus) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).get(username);
                    if (seckillStatus != null) {

                        SeckillGoods seckillGoods = (SeckillGoods) redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + seckillStatus.getTime()).get(seckillStatus.getGoodsId());
                        if(seckillGoods==null){
                            //从数据库获取商品
                            seckillGoods = seckillGoodsMapper.selectByPrimaryKey(seckillStatus.getGoodsId());
                        }
                        //恢复库存    上锁
                        RLock myLock = redissonClient.getLock("myLock"+seckillStatus.getGoodsId());
                        try {
                            myLock.lock(10, TimeUnit.SECONDS);
                            seckillGoods.setStockCount(seckillGoods.getStockCount()+1);
                            redisTemplate.boundHashOps(SystemConstants.SEC_KILL_GOODS_PREFIX + seckillStatus.getTime()).put(seckillStatus.getGoodsId(),seckillGoods);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }finally {
                            myLock.unlock();
                        }

                        //删除redis中的订单
                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_ORDER_KEY).delete(username);

                        //清除重复排队标识
                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_QUEUE_REPEAT_KEY).delete(username);

                        //清除用户的抢单信息
                        redisTemplate.boundHashOps(SystemConstants.SEC_KILL_USER_STATUS_KEY).delete(username);

                        //关闭微信支付订单
                        try {
                            weixinPayFeign.closePay(Long.valueOf(map.get("out_trade_no")));
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

}